/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 *
 * $Id: TaskCtrlData.hpp,v 1.12 2009-12-18 13:00:11 mmatusia Exp $
 * 
 * \file
 * \brief Protocol encoder/decoder header for the TaskCtrl protocol.
 * \author Antti Maula <antti.maula@tkk.fi>, Marek Matusiak
 */
#ifndef _MACI_TASKCTRLDATA_HPP_
#define _MACI_TASKCTRLDATA_HPP_
#include "TaskCtrlTypes.hpp"
#include "MaCIData.hpp"
#include "common/timestamp.hpp"
#include <vector>
#include <map>

namespace gim {
  namespace binbag{class CBinBag;}
}

namespace MaCI {
  namespace TaskCtrl {
    
    typedef std::vector<const MaCI::TaskCtrl::TTaskCtrlEvaluation*> TTaskCtrlEvaluationPtrArray;
    typedef std::vector<const MaCI::TaskCtrl::TTaskCtrlXML*> TTaskCtrlXMLPtrArray;
    typedef std::vector<const MaCI::TaskCtrl::TTaskCtrlXML> TTaskCtrlXMLArray;
    typedef std::vector<const MaCI::TaskCtrl::TTaskCtrlContract*> TTaskCtrlContractPtrArray;
    typedef std::vector<const MaCI::TaskCtrl::TTaskCtrlTaskState*> TTaskCtrlTaskStatePtrArray;
    typedef std::vector<MaCI::TaskCtrl::TTaskCtrlTaskState> TTaskCtrlTaskStateArray;
    
    //********************************************************************************************
    //*******************PYTHON CONTAINERS********************************************************
    //********************************************************************************************
 

    
    class  TTaskCtrlTaskStateContainer
    {
    public:
     TTaskCtrlTaskStateContainer(void) 
       : array() {}
      
      TTaskCtrlTaskStateContainer(const std::vector< MaCI::TaskCtrl::TTaskCtrlTaskState > &aArray) 
        : array(aArray) {}

      std::vector<  TTaskCtrlTaskState > array;

      inline const unsigned int GetArraySize(void) const {
        return array.size();
      }
      inline const  TTaskCtrlTaskState GetArrayElement(const unsigned int aIndex) {
        return array[aIndex];
      }
      inline void Clear(void) {
        array.clear();
      }
    };

    class TStringContainer
    {
    public:
      TStringContainer(void)
        : array() {}
      
      TStringContainer(const std::vector< std::string > &aArray) 
         : array(aArray) {}

      std::vector<  std::string > array;

      inline const unsigned int GetArraySize(void) const {
        return array.size();
      }
      inline const  std::string GetArrayElement(const unsigned int aIndex) {
        return array[aIndex];
      }
      inline void Clear(void) {
        array.clear();
      }

    };

    //********************************************************************************************
    //*******************PYTHON CONTAINERS END****************************************************
    //********************************************************************************************




    /** TaskCtrl protocol parser.
     *
     * This class contains the methods for decoding/encoding a 
     * TaskCtrl message.
     */
    class CTaskCtrlData : public MaCI::CMaCIData
    {
    public:
      CTaskCtrlData(void);
      ~CTaskCtrlData();

      // Copy constructor.
      CTaskCtrlData(const CTaskCtrlData &aD);

      // Assignment operator.
      CTaskCtrlData &operator=(const CTaskCtrlData &aD);

      // Interface for moving data around
      bool DecodeFrom(gim::binbag::CBinBag *aBinBag = NULL);
      void Reset();
      void Print(const int level) const;


      /** Set timestamp element.
       * 
       */
      bool SetTimestamp(const MaCI::Common::TTimestamp &aStamp);


      /** Add command element.
       * This function stores a element of type TCommand.
       *
       * @return                'true' if element was succesfully added,
       *                        'false' if element already exists.
       */
      bool SetCommand(const MaCI::TaskCtrl::TCommand &aCmd);
       
      /** Add a TaskCtrlEvaluation element.
      *
      * This function stores a element of type TTaskCtrlEvaluation.
      *
      *
      * @return                'true' if element was succesfully added,
      *                        'false' if element already exists.
      */     
      
      bool AddTaskCtrlEvaluation (const MaCI::TaskCtrl::TTaskCtrlEvaluation &aTaskCtrlEvaluation);
       
       /** Set TTaskCtrlStateCommand element.
       *
       * This function stores a element of type TTaskCtrlStateCommand.
       *
       *
       * @return                'true' if element was succesfully added,
       *                        'false' if element already exists.
       */

      bool SetTaskCtrlStateCommand(const MaCI::TaskCtrl::TTaskCtrlStateCommand &aTaskCtrlStateCommand);
       
      
       /** Set TTaskCtrlReward element.
       *
       * This function stores a element of type TTaskCtrlReward.
       *
       *
       * @return                'true' if element was succesfully added,
       *                        'false' if element already exists.
       */
        
      bool SetTaskCtrlReward(const MaCI::TaskCtrl::TTaskCtrlReward &aTaskCtrlReward); 
      
       /** Set TTaskCtrlContract element.
       *
       * This function stores a element of type TTaskCtrlContract.
       *
       *
       * @return                'true' if element was succesfully added,
       *                        'false' if element already exists.
       */
        
      //bool SetTaskCtrlContract(const TTaskCtrlContract &aTaskCtrlContract); 
      bool AddTaskCtrlContract (const MaCI::TaskCtrl::TTaskCtrlContract &aContract);
      
      /** Set TaskCtrlEvent element.
       *
       * This function stores a element of type TTaskCtrlEvent.
       *
       *
       * @return                'true' if element was succesfully added,
       *                        'false' if element already exists.
       */

      bool SetTaskCtrlStatusEvent(const MaCI::TaskCtrl::TTaskCtrlStatusEvent &aEvent);
      
      /** Set TaskCtrlEvent element.
       *
       * This function stores a element of type TTaskCtrlEvent.
       *
       *
       * @return                'true' if element was succesfully added,
       *                        'false' if element already exists.
       */

      bool SetTaskCtrlTaskState(const MaCI::TaskCtrl::TTaskCtrlTaskState &aState);
      
      /** Add  TTaskCtrlXML
       *
       * This function stores a element of type TTaskCtrlXML
       *
       *
       * @return                'true' if element was succesfully added,
       *                        'false' if read only container
       */
      bool AddTaskCtrlXML(const MaCI::TaskCtrl::TTaskCtrlXML &aXML);

      /** Add TaskCtrlXML by creating one from a std::string.
       *
       * @param[in] aXmlString   String to encode as TaskCtrlXML.
       * @return                'true' if element was succesfully added,
       *                        'false' if element already exists.
       */
      bool AddTaskCtrlXMLString(const std::string &aXmlString);

      /** Add  TErrorStrign
       *
       * This function stores a element of type TErrorString
       *
       *
       * @return                'true' if element was succesfully added,
       *                        'false' if read only container
       */
      bool AddErrorString(const MaCI::TaskCtrl::TErrorString &aXML);


      /** Add TErrorString by creating one from a std::string.
       *
       * @param[in] aXmlString   String to encode as TaskCtrlXML.
       * @return                'true' if element was succesfully added,
       *                        'false' if element already exists.
       */
      bool AddErrorString(const std::string &aErrorString);

      /** Add  TTaskCtrlContractedTask
       *
       * This function stores a element of type TTaskCtrlContractedTask
       *
       *
       * @return                'true' if element was succesfully added,
       *                        'false' if read only container
       */
      
       
      const MaCI::Common::TTimestamp *GetTimestamp(void) const;
      
      /** Get pointer to TCommand array.
       *
       * @return                 Pointer to element if such exists, 
       *                         NULL if element doesn't exists in the
       *                         container.
       */
      const MaCI::TaskCtrl::TCommand *GetCommand(void) const;


      /** Get pointer to TServiceInfo element.
       *
       * @return                 Pointer to element if such exists, 
       *                         NULL if element doesn't exists in the
       *                         container.
       */
      const MaCI::TaskCtrl::TTaskCtrlEvaluationPtrArray &GetTaskCtrlEvaluationArray(void) const;

      /** Get pointer to TTaskCtrlStatusEvent element.
       *
       * @return                 Pointer to element if such exists, 
       *                         NULL if element doesn't exists in the
       *                         container.
       */
      const MaCI::TaskCtrl::TTaskCtrlStatusEvent *GetTaskCtrlStatusEvent(void) const;
      
      /** Get pointer to GetTaskCtrlTaskState element. If there are multiple
       * TTakCtrlTaskState-elements, the first one is returned. If you want them
       * all, use GetTaskCtrlTaskStatePtrArray-function instead
       *
       * @return                 Pointer to element if such exists, 
       *                         NULL if element doesn't exists in the
       *                         container.
       */
      const MaCI::TaskCtrl::TTaskCtrlTaskState *GetTaskCtrlTaskState(void) const;

      /**
       * 
       */
      const  MaCI::TaskCtrl::TTaskCtrlTaskStatePtrArray &GetTaskCtrlTaskStatePtrArray(void) const;

      /** Get pointer to TTaskCtrlStatusEvent element.
       *
       * @return                 Pointer to element if such exists, 
       *                         NULL if element doesn't exists in the
       *                         container.
       */
      const MaCI::TaskCtrl::TTaskCtrlStateCommand *GetTaskCtrlStateCommand(void) const;
      
      
      /** Get pointer to TTaskCtrlReward element.
       *
       * @return                 Pointer to element if such exists, 
       *                         NULL if element doesn't exists in the
       *                         container.
       */
      const MaCI::TaskCtrl::TTaskCtrlReward *GetTaskCtrlReward(void) const;
      
        /** Get pointer to TTaskCtrlContract element.
       *
       * @return                 Pointer to element if such exists, 
       *                         NULL if element doesn't exists in the
       *                         container.
       */
      //const TTaskCtrlContract *GetTaskCtrlContract(void) const;
      const MaCI::TaskCtrl::TTaskCtrlContractPtrArray &GetTaskCtrlContractPtrArray(void) const;
      
      /** Get pointer to TTaskCtrlXML
       *
       * @return                 Pointer to element if such exists, 
       *                         NULL if element doesn't exists in the
       *                         container.
       */
      const MaCI::TaskCtrl::TTaskCtrlXMLPtrArray &GetTaskCtrlXMLPtrArray(void) const;



      /** Get pointer to TTaskCtrlContractedTaskPtrArray
       *
       * @return                 Pointer to element if such exists, 
       *                         NULL if element doesn't exists in the
       *                         container.
       */

      std::string GetTaskCtrlXMLString(void) const;

      /** Get pointer to TTaskCtrlContractedTaskPtrArray
       *
       * @return                 Pointer to element if such exists, 
       *                         NULL if element doesn't exists in the
       *                         container.
       */

      std::string GetTaskCtrlErrorString(void) const;

    private:
      const MaCI::Common::TTimestamp *iTimestampPtr; ///< Pointer to timestamp if exists
      const MaCI::TaskCtrl::TCommand *iCommandPtr; ///< Pointer to command if any.
      const MaCI::TaskCtrl::TTaskCtrlStatusEvent *iTaskCtrlStatusEventPtr; ///< Pointer to TaskCtrl event.
      const MaCI::TaskCtrl::TTaskCtrlTaskState *iTaskCtrlTaskStatePtr; ///< Pointer to TaskCtrl event.
      const MaCI::TaskCtrl::TTaskCtrlStateCommand *iTaskCtrlStateCommandPtr;///< Pointer to state command element.
      const MaCI::TaskCtrl::TTaskCtrlReward *iTaskCtrlRewardPtr;///< Pointer to reward element.
      const MaCI::TaskCtrl::TTaskCtrlContract *iTaskCtrlContractPtr;///< Pointer to contract element.
      const MaCI::TaskCtrl::TErrorString *iErrorStringPtr; ///Pointer to error string element
      MaCI::TaskCtrl::TTaskCtrlXMLPtrArray iTaskCtrlXMLPtrArray; ///< Pointer to TaskCtrlXML element.

      MaCI::TaskCtrl::TTaskCtrlEvaluationPtrArray iTaskCtrlEvaluationPtrArray;
      MaCI::TaskCtrl::TTaskCtrlContractPtrArray iTaskCtrlContractPtrArray;

      MaCI::TaskCtrl::TTaskCtrlTaskStatePtrArray iTaskCtrlStatePtrArray;
    };
    
  }
}

#endif
